package com.commutersconnect.model {

import net.liftweb._
import mapper._
import util._
import common._

/**
 * Companion class for Report.  Provides database access using the Lift Mapper
 * API.
 */
object Report
  extends Report
  with LongKeyedMetaMapper[Report] {
  override def dbTableName = "reports"
}

/**
 * A Report is any information that has been reported to the system by a user.
 * Not much to it is required, the point is that we allow individuals to
 * report information easily.  As such, a Report is typically just an attached
 * image with a latitude and longitude.  Note that we do require a location
 * before the report is saved.  Our UI does not have a method to change this
 * after you have created a report.
 */
class Report
  extends LongKeyedMapper[Report]
  with CreatedUpdated with IdPK
  with OneToMany[Long, Report] {
  def getSingleton = Report // Required for Mapper API.

  object subject extends MappedString(this, 256) {
    override def validations = {
      valMinLen(4, "Please give us a longer subject.") _ ::
      valMaxLen(256, "Unfortunately, we can not take that large of a subject.") _ :: Nil
    }
  }

  object text extends MappedString(this, 512) {
    override def validations = {
      valMinLen(16, "Please give us a longer description.") _ ::
      valMaxLen(512, "Unfortunately, we can not take that large of a descriptoin.") _ :: Nil
    }
  }

  //We add a validation to latitude only for required location, assuming that
  //we will not set latitude without setting longitude.
  object latitude extends MappedDouble(this) {
    def validateExists(in:Double):List[FieldError] = {
      if (in == 0.0) {
        List(FieldError(this, "We need a location."))
      } else {
        Nil
      }
    }

    override def validations = validateExists _ :: Nil
  }

  object longitude extends MappedDouble(this)

  object status extends MappedEnum(this, ReportStatus)

  object messages extends MappedOneToMany(Message, Message.report)

  object images extends MappedOneToMany(Img, Img.report)

  object reporter extends MappedLongForeignKey(this, User)
}

/**
 * As seen above, a Report has a status.  Currently, we are keeping this as a
 * value of a simple enum.
 */
object ReportStatus extends Enumeration {
  val open = Value(1, "Open")
  val closed = Value(2, "Closed")
}

/**
 * An Img is... an image.  Storing in the database for now to avoid any
 * concerns with having a writable location on the filesystem where I can
 * store them.  We currently store the image as a raw byte array.  No metadata
 * is pulled out and stored in an indexable fashion.
 */
class Img
  extends LongKeyedMapper[Img]
  with CreatedUpdated with IdPK {
  def getSingleton = Img

  object data extends MappedBinary(this)

  object report extends MappedLongForeignKey(this, Report)
}

/**
 * Companion class for Img.  Provides database access using the Lift Mapper
 * API.
 */
object Img
  extends Img
  with LongKeyedMetaMapper[Img] {
    override def dbTableName = "images"
}
}
